#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""错误处理工具模块"""

import sys
import traceback
import logging
from typing import Any, Callable, Dict, List, Optional, Tuple, Type, Union
import functools


class ErrorHandler:
    """错误处理类，提供统一的错误处理机制"""
    
    def __init__(self, logger: Optional[logging.Logger] = None):
        """初始化错误处理器
        
        Args:
            logger: 日志记录器，如果为None则使用默认日志记录器
        """
        self._logger = logger or logging.getLogger(__name__)
        # 注册的错误处理器
        self._error_handlers: Dict[Type[Exception], List[Callable]] = {}
        # 默认错误处理器
        self._default_handler: Optional[Callable] = None
    
    def register_handler(self, exception_type: Type[Exception], handler: Callable) -> bool:
        """注册错误处理器
        
        Args:
            exception_type: 异常类型
            handler: 处理函数，接收异常对象作为参数
            
        Returns:
            bool: 是否注册成功
        """
        if not callable(handler):
            return False
        
        if exception_type not in self._error_handlers:
            self._error_handlers[exception_type] = []
        
        if handler not in self._error_handlers[exception_type]:
            self._error_handlers[exception_type].append(handler)
        
        return True
    
    def unregister_handler(self, exception_type: Type[Exception], handler: Callable) -> bool:
        """取消注册错误处理器
        
        Args:
            exception_type: 异常类型
            handler: 处理函数
            
        Returns:
            bool: 是否取消注册成功
        """
        if exception_type not in self._error_handlers:
            return False
        
        if handler not in self._error_handlers[exception_type]:
            return False
        
        self._error_handlers[exception_type].remove(handler)
        
        # 如果没有处理器了，删除该异常类型
        if not self._error_handlers[exception_type]:
            del self._error_handlers[exception_type]
        
        return True
    
    def set_default_handler(self, handler: Callable) -> None:
        """设置默认错误处理器
        
        Args:
            handler: 默认处理函数，接收异常对象作为参数
        """
        if callable(handler):
            self._default_handler = handler
    
    def clear_default_handler(self) -> None:
        """清除默认错误处理器"""
        self._default_handler = None
    
    def handle(self, exception: Exception) -> Any:
        """处理异常
        
        Args:
            exception: 异常对象
            
        Returns:
            Any: 处理器的返回值
        """
        # 获取异常类型
        exception_type = type(exception)
        
        # 检查是否有该异常类型的处理器
        if exception_type in self._error_handlers:
            results = []
            for handler in self._error_handlers[exception_type]:
                try:
                    result = handler(exception)
                    results.append(result)
                except Exception as e:
                    # 记录处理器本身的错误
                    self._logger.error(f"Error in exception handler: {e}")
            return results if len(results) > 1 else (results[0] if results else None)
        
        # 检查是否有父类异常的处理器
        for registered_type, handlers in self._error_handlers.items():
            if issubclass(exception_type, registered_type):
                results = []
                for handler in handlers:
                    try:
                        result = handler(exception)
                        results.append(result)
                    except Exception as e:
                        self._logger.error(f"Error in exception handler: {e}")
                return results if len(results) > 1 else (results[0] if results else None)
        
        # 使用默认处理器
        if self._default_handler:
            try:
                return self._default_handler(exception)
            except Exception as e:
                self._logger.error(f"Error in default exception handler: {e}")
        
        # 默认行为：记录错误并重新抛出
        self._log_exception(exception)
        raise
    
    def _log_exception(self, exception: Exception) -> None:
        """记录异常信息
        
        Args:
            exception: 异常对象
        """
        # 获取异常信息和堆栈跟踪
        exc_type, exc_value, exc_traceback = sys.exc_info()
        if exc_type is None:
            exc_type = type(exception)
            exc_value = exception
            exc_traceback = exception.__traceback__
        
        # 格式化异常信息
        error_message = f"{exc_type.__name__}: {exc_value}"
        stack_trace = ''.join(traceback.format_tb(exc_traceback))
        
        # 记录错误
        self._logger.error(f"Unhandled exception: {error_message}\nStack trace:\n{stack_trace}")
    
    def wrap(self, func: Callable) -> Callable:
        """包装函数，捕获并处理其中的异常
        
        Args:
            func: 要包装的函数
            
        Returns:
            Callable: 包装后的函数
        """
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except Exception as e:
                return self.handle(e)
        
        return wrapper
    
    def clear_handlers(self, exception_type: Optional[Type[Exception]] = None) -> None:
        """清除错误处理器
        
        Args:
            exception_type: 异常类型，如果为None则清除所有处理器
        """
        if exception_type is None:
            self._error_handlers.clear()
        elif exception_type in self._error_handlers:
            del self._error_handlers[exception_type]
    
    def get_handlers(self, exception_type: Type[Exception]) -> List[Callable]:
        """获取指定异常类型的处理器列表
        
        Args:
            exception_type: 异常类型
            
        Returns:
            List[Callable]: 处理器列表
        """
        if exception_type not in self._error_handlers:
            return []
        
        return self._error_handlers[exception_type].copy()
    
    def get_registered_exception_types(self) -> List[Type[Exception]]:
        """获取所有注册的异常类型
        
        Returns:
            List[Type[Exception]]: 异常类型列表
        """
        return list(self._error_handlers.keys())


class ErrorContext:
    """错误上下文管理器，用于在特定上下文中处理错误"""
    
    def __init__(self, error_handler: ErrorHandler, suppress_exceptions: bool = False):
        """初始化错误上下文管理器
        
        Args:
            error_handler: 错误处理器
            suppress_exceptions: 是否抑制异常（不向上传播）
        """
        self._error_handler = error_handler
        self._suppress_exceptions = suppress_exceptions
        self._exception: Optional[Exception] = None
        self._result: Any = None
    
    def __enter__(self) -> 'ErrorContext':
        """进入上下文"""
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb) -> bool:
        """退出上下文，处理异常
        
        Returns:
            bool: 是否抑制异常
        """
        if exc_type is not None:
            self._exception = exc_val
            try:
                self._result = self._error_handler.handle(exc_val)
            except Exception:
                # 如果处理器本身也抛出异常，并且设置了抑制异常，则返回True
                if self._suppress_exceptions:
                    return True
                # 否则不抑制异常，让它继续传播
                return False
            
            # 如果处理成功，根据设置决定是否抑制异常
            return self._suppress_exceptions
        
        return False
    
    @property
    def exception(self) -> Optional[Exception]:
        """获取捕获的异常
        
        Returns:
            Optional[Exception]: 异常对象
        """
        return self._exception
    
    @property
    def result(self) -> Any:
        """获取错误处理器的返回值
        
        Returns:
            Any: 处理器的返回值
        """
        return self._result
    
    @property
    def has_exception(self) -> bool:
        """检查是否捕获了异常
        
        Returns:
            bool: 是否捕获了异常
        """
        return self._exception is not None


class ExceptionLogger:
    """异常日志记录器"""
    
    def __init__(self, logger: Optional[logging.Logger] = None):
        """初始化异常日志记录器
        
        Args:
            logger: 日志记录器，如果为None则使用默认日志记录器
        """
        self._logger = logger or logging.getLogger(__name__)
    
    def log_exception(self, exception: Exception, level: int = logging.ERROR, extra_info: Optional[Dict[str, Any]] = None) -> None:
        """记录异常信息
        
        Args:
            exception: 异常对象
            level: 日志级别
            extra_info: 额外信息
        """
        # 获取异常信息和堆栈跟踪
        exc_type, exc_value, exc_traceback = sys.exc_info()
        if exc_type is None:
            exc_type = type(exception)
            exc_value = exception
            exc_traceback = exception.__traceback__
        
        # 格式化异常信息
        error_message = f"{exc_type.__name__}: {exc_value}"
        stack_trace = ''.join(traceback.format_tb(exc_traceback))
        
        # 构建日志消息
        log_message = f"Exception: {error_message}\nStack trace:\n{stack_trace}"
        
        # 添加额外信息
        if extra_info:
            extra_info_str = "\nExtra info:\n"
            for key, value in extra_info.items():
                extra_info_str += f"  {key}: {value}\n"
            log_message += extra_info_str
        
        # 记录日志
        self._logger.log(level, log_message)
    
    def log_and_raise(self, exception: Exception, level: int = logging.ERROR, extra_info: Optional[Dict[str, Any]] = None) -> None:
        """记录异常信息并重新抛出
        
        Args:
            exception: 异常对象
            level: 日志级别
            extra_info: 额外信息
        """
        self.log_exception(exception, level, extra_info)
        raise
    
    def wrap(self, func: Callable, level: int = logging.ERROR, extra_info: Optional[Dict[str, Any]] = None, re_raise: bool = True) -> Callable:
        """包装函数，记录并（可选）重新抛出异常
        
        Args:
            func: 要包装的函数
            level: 日志级别
            extra_info: 额外信息
            re_raise: 是否重新抛出异常
            
        Returns:
            Callable: 包装后的函数
        """
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except Exception as e:
                # 合并额外信息
                merged_extra_info = {}
                if extra_info:
                    merged_extra_info.update(extra_info)
                
                # 添加函数信息
                merged_extra_info['function'] = func.__name__
                merged_extra_info['args'] = args
                merged_extra_info['kwargs'] = kwargs
                
                # 记录异常
                self.log_exception(e, level, merged_extra_info)
                
                # 是否重新抛出
                if re_raise:
                    raise
                
                return None
        
        return wrapper
    
    def set_logger(self, logger: logging.Logger) -> None:
        """设置日志记录器
        
        Args:
            logger: 日志记录器
        """
        if isinstance(logger, logging.Logger):
            self._logger = logger


class ErrorInfo:
    """错误信息类，用于存储和表示错误信息"""
    
    def __init__(self, error_code: int = 0, message: str = "", details: Optional[Dict[str, Any]] = None, exception: Optional[Exception] = None):
        """初始化错误信息
        
        Args:
            error_code: 错误码
            message: 错误消息
            details: 详细信息
            exception: 关联的异常对象
        """
        self._error_code = error_code
        self._message = message
        self._details = details or {}
        self._exception = exception
        self._timestamp = None
        self._source = None
        
        # 如果提供了异常对象，自动填充一些信息
        if exception:
            if not message:
                self._message = str(exception)
            
            if 'exception_type' not in self._details:
                self._details['exception_type'] = type(exception).__name__
            
            # 获取堆栈信息
            if 'stack_trace' not in self._details:
                exc_type, exc_value, exc_traceback = sys.exc_info()
                if exc_traceback:
                    self._details['stack_trace'] = ''.join(traceback.format_tb(exc_traceback))
    
    @property
    def error_code(self) -> int:
        """获取错误码
        
        Returns:
            int: 错误码
        """
        return self._error_code
    
    @error_code.setter
    def error_code(self, value: int) -> None:
        """设置错误码
        
        Args:
            value: 错误码
        """
        self._error_code = value
    
    @property
    def message(self) -> str:
        """获取错误消息
        
        Returns:
            str: 错误消息
        """
        return self._message
    
    @message.setter
    def message(self, value: str) -> None:
        """设置错误消息
        
        Args:
            value: 错误消息
        """
        self._message = value
    
    @property
    def details(self) -> Dict[str, Any]:
        """获取详细信息
        
        Returns:
            Dict[str, Any]: 详细信息
        """
        return self._details
    
    @details.setter
    def details(self, value: Dict[str, Any]) -> None:
        """设置详细信息
        
        Args:
            value: 详细信息
        """
        self._details = value or {}
    
    @property
    def exception(self) -> Optional[Exception]:
        """获取关联的异常对象
        
        Returns:
            Optional[Exception]: 异常对象
        """
        return self._exception
    
    @exception.setter
    def exception(self, value: Exception) -> None:
        """设置关联的异常对象
        
        Args:
            value: 异常对象
        """
        self._exception = value
    
    @property
    def timestamp(self) -> Optional[float]:
        """获取时间戳
        
        Returns:
            Optional[float]: 时间戳
        """
        return self._timestamp
    
    @timestamp.setter
    def timestamp(self, value: float) -> None:
        """设置时间戳
        
        Args:
            value: 时间戳
        """
        self._timestamp = value
    
    @property
    def source(self) -> Optional[str]:
        """获取错误来源
        
        Returns:
            Optional[str]: 错误来源
        """
        return self._source
    
    @source.setter
    def source(self, value: str) -> None:
        """设置错误来源
        
        Args:
            value: 错误来源
        """
        self._source = value
    
    def add_detail(self, key: str, value: Any) -> 'ErrorInfo':
        """添加详细信息
        
        Args:
            key: 键
            value: 值
            
        Returns:
            ErrorInfo: 自身，用于链式调用
        """
        self._details[key] = value
        return self
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典
        
        Returns:
            Dict[str, Any]: 字典表示
        """
        result = {
            'error_code': self._error_code,
            'message': self._message,
            'details': self._details,
        }
        
        if self._timestamp is not None:
            result['timestamp'] = self._timestamp
        
        if self._source is not None:
            result['source'] = self._source
        
        return result
    
    def __str__(self) -> str:
        """字符串表示
        
        Returns:
            str: 字符串表示
        """
        return f"Error {self._error_code}: {self._message}"
    
    def __repr__(self) -> str:
        """对象表示
        
        Returns:
            str: 对象表示
        """
        return f"ErrorInfo(error_code={self._error_code}, message='{self._message}')"


class ErrorCodes:
    """错误码常量类"""
    # 通用错误码
    SUCCESS = 0
    UNKNOWN_ERROR = 1
    INVALID_INPUT = 2
    PERMISSION_DENIED = 3
    RESOURCE_NOT_FOUND = 4
    RESOURCE_ALREADY_EXISTS = 5
    NETWORK_ERROR = 6
    TIMEOUT_ERROR = 7
    DATABASE_ERROR = 8
    VALIDATION_ERROR = 9
    AUTHENTICATION_ERROR = 10
    UNAUTHORIZED_ACCESS = 11
    SERVER_ERROR = 12
    CLIENT_ERROR = 13
    CONFIGURATION_ERROR = 14
    DEPENDENCY_ERROR = 15
    RATE_LIMIT_EXCEEDED = 16
    
    # 文件操作错误码
    FILE_NOT_FOUND = 100
    FILE_ACCESS_ERROR = 101
    FILE_PERMISSION_ERROR = 102
    FILE_FORMAT_ERROR = 103
    FILE_SIZE_ERROR = 104
    FILE_UPLOAD_ERROR = 105
    FILE_DOWNLOAD_ERROR = 106
    FILE_WRITE_ERROR = 107
    FILE_READ_ERROR = 108
    FILE_DELETE_ERROR = 109
    FILE_RENAME_ERROR = 110
    FILE_COPY_ERROR = 111
    FILE_MOVE_ERROR = 112
    
    # 项目操作错误码
    PROJECT_NOT_FOUND = 200
    PROJECT_ACCESS_ERROR = 201
    PROJECT_PERMISSION_ERROR = 202
    PROJECT_CONFIG_ERROR = 203
    PROJECT_IMPORT_ERROR = 204
    PROJECT_EXPORT_ERROR = 205
    PROJECT_VALIDATION_ERROR = 206
    
    # 编辑器错误码
    EDITOR_ERROR = 300
    EDITOR_SYNTAX_ERROR = 301
    EDITOR_PARSE_ERROR = 302
    EDITOR_COMPLETION_ERROR = 303
    EDITOR_HIGHLIGHT_ERROR = 304
    
    # 设计器错误码
    DESIGNER_ERROR = 400
    DESIGNER_COMPONENT_ERROR = 401
    DESIGNER_LAYOUT_ERROR = 402
    DESIGNER_PROPERTY_ERROR = 403
    
    # 构建和运行错误码
    BUILD_ERROR = 500
    BUILD_COMPILE_ERROR = 501
    BUILD_LINK_ERROR = 502
    BUILD_DEPENDENCY_ERROR = 503
    RUN_ERROR = 504
    RUN_TIMEOUT_ERROR = 505
    
    # 调试错误码
    DEBUG_ERROR = 600
    DEBUG_CONNECTION_ERROR = 601
    DEBUG_BREAKPOINT_ERROR = 602
    DEBUG_EXECUTION_ERROR = 603
    
    # 资源错误码
    RESOURCE_ERROR = 700
    RESOURCE_LOAD_ERROR = 701
    RESOURCE_SAVE_ERROR = 702
    RESOURCE_VALIDATION_ERROR = 703
    
    # 网络错误码
    NETWORK_CONNECTION_ERROR = 800
    NETWORK_TIMEOUT_ERROR = 801
    NETWORK_SERVER_ERROR = 802
    NETWORK_CLIENT_ERROR = 803
    NETWORK_AUTH_ERROR = 804
    
    # 系统错误码
    SYSTEM_ERROR = 900
    MEMORY_ERROR = 901
    CPU_ERROR = 902
    DISK_ERROR = 903
    SYSTEM_RESOURCE_ERROR = 904


class CustomException(Exception):
    """自定义异常基类"""
    
    def __init__(self, error_code: int = ErrorCodes.UNKNOWN_ERROR, message: str = "", details: Optional[Dict[str, Any]] = None):
        """初始化自定义异常
        
        Args:
            error_code: 错误码
            message: 错误消息
            details: 详细信息
        """
        super().__init__(message)
        self.error_code = error_code
        self.details = details or {}
    
    def __str__(self) -> str:
        """字符串表示
        
        Returns:
            str: 字符串表示
        """
        return f"{self.__class__.__name__}({self.error_code}): {super().__str__()}"
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典
        
        Returns:
            Dict[str, Any]: 字典表示
        """
        return {
            'error_code': self.error_code,
            'message': str(self),
            'details': self.details,
            'exception_type': self.__class__.__name__
        }


class FileOperationException(CustomException):
    """文件操作异常"""
    
    def __init__(self, error_code: int = ErrorCodes.FILE_ACCESS_ERROR, message: str = "", file_path: str = "", details: Optional[Dict[str, Any]] = None):
        """初始化文件操作异常
        
        Args:
            error_code: 错误码
            message: 错误消息
            file_path: 文件路径
            details: 详细信息
        """
        _details = details or {}
        if file_path:
            _details['file_path'] = file_path
        
        super().__init__(error_code, message, _details)
        self.file_path = file_path


class ProjectOperationException(CustomException):
    """项目操作异常"""
    
    def __init__(self, error_code: int = ErrorCodes.PROJECT_ACCESS_ERROR, message: str = "", project_path: str = "", details: Optional[Dict[str, Any]] = None):
        """初始化项目操作异常
        
        Args:
            error_code: 错误码
            message: 错误消息
            project_path: 项目路径
            details: 详细信息
        """
        _details = details or {}
        if project_path:
            _details['project_path'] = project_path
        
        super().__init__(error_code, message, _details)
        self.project_path = project_path


class EditorException(CustomException):
    """编辑器异常"""
    
    def __init__(self, error_code: int = ErrorCodes.EDITOR_ERROR, message: str = "", file_path: str = "", line: int = -1, column: int = -1, details: Optional[Dict[str, Any]] = None):
        """初始化编辑器异常
        
        Args:
            error_code: 错误码
            message: 错误消息
            file_path: 文件路径
            line: 行号
            column: 列号
            details: 详细信息
        """
        _details = details or {}
        if file_path:
            _details['file_path'] = file_path
        if line >= 0:
            _details['line'] = line
        if column >= 0:
            _details['column'] = column
        
        super().__init__(error_code, message, _details)
        self.file_path = file_path
        self.line = line
        self.column = column


class DesignerException(CustomException):
    """设计器异常"""
    
    def __init__(self, error_code: int = ErrorCodes.DESIGNER_ERROR, message: str = "", component_name: str = "", property_name: str = "", details: Optional[Dict[str, Any]] = None):
        """初始化设计器异常
        
        Args:
            error_code: 错误码
            message: 错误消息
            component_name: 组件名称
            property_name: 属性名称
            details: 详细信息
        """
        _details = details or {}
        if component_name:
            _details['component_name'] = component_name
        if property_name:
            _details['property_name'] = property_name
        
        super().__init__(error_code, message, _details)
        self.component_name = component_name
        self.property_name = property_name


class BuildException(CustomException):
    """构建异常"""
    
    def __init__(self, error_code: int = ErrorCodes.BUILD_ERROR, message: str = "", build_log: str = "", details: Optional[Dict[str, Any]] = None):
        """初始化构建异常
        
        Args:
            error_code: 错误码
            message: 错误消息
            build_log: 构建日志
            details: 详细信息
        """
        _details = details or {}
        if build_log:
            _details['build_log'] = build_log
        
        super().__init__(error_code, message, _details)
        self.build_log = build_log


class DebugException(CustomException):
    """调试异常"""
    
    def __init__(self, error_code: int = ErrorCodes.DEBUG_ERROR, message: str = "", debug_info: str = "", details: Optional[Dict[str, Any]] = None):
        """初始化调试异常
        
        Args:
            error_code: 错误码
            message: 错误消息
            debug_info: 调试信息
            details: 详细信息
        """
        _details = details or {}
        if debug_info:
            _details['debug_info'] = debug_info
        
        super().__init__(error_code, message, _details)
        self.debug_info = debug_info


# 创建全局错误处理器实例
global_error_handler = ErrorHandler()
global_exception_logger = ExceptionLogger()


# 导出常用函数
def handle_error(exception: Exception) -> Any:
    """处理异常
    
    Args:
        exception: 异常对象
        
    Returns:
        Any: 处理器的返回值
    """
    return global_error_handler.handle(exception)

def log_exception(exception: Exception, level: int = logging.ERROR, extra_info: Optional[Dict[str, Any]] = None) -> None:
    """记录异常信息
    
    Args:
        exception: 异常对象
        level: 日志级别
        extra_info: 额外信息
    """
    global_exception_logger.log_exception(exception, level, extra_info)

def log_and_raise(exception: Exception, level: int = logging.ERROR, extra_info: Optional[Dict[str, Any]] = None) -> None:
    """记录异常信息并重新抛出
    
    Args:
        exception: 异常对象
        level: 日志级别
        extra_info: 额外信息
    """
    global_exception_logger.log_and_raise(exception, level, extra_info)

def error_context(suppress_exceptions: bool = False) -> ErrorContext:
    """创建错误上下文管理器
    
    Args:
        suppress_exceptions: 是否抑制异常
        
    Returns:
        ErrorContext: 错误上下文管理器
    """
    return ErrorContext(global_error_handler, suppress_exceptions)

def register_error_handler(exception_type: Type[Exception], handler: Callable) -> bool:
    """注册错误处理器
    
    Args:
        exception_type: 异常类型
        handler: 处理函数
        
    Returns:
        bool: 是否注册成功
    """
    return global_error_handler.register_handler(exception_type, handler)

def unregister_error_handler(exception_type: Type[Exception], handler: Callable) -> bool:
    """取消注册错误处理器
    
    Args:
        exception_type: 异常类型
        handler: 处理函数
        
    Returns:
        bool: 是否取消注册成功
    """
    return global_error_handler.unregister_handler(exception_type, handler)

def set_default_error_handler(handler: Callable) -> None:
    """设置默认错误处理器
    
    Args:
        handler: 默认处理函数
    """
    global_error_handler.set_default_handler(handler)

def with_error_handling(func: Callable) -> Callable:
    """装饰器：添加错误处理
    
    Args:
        func: 要装饰的函数
        
    Returns:
        Callable: 装饰后的函数
    """
    return global_error_handler.wrap(func)

def with_exception_logging(func: Callable, level: int = logging.ERROR, extra_info: Optional[Dict[str, Any]] = None, re_raise: bool = True) -> Callable:
    """装饰器：添加异常日志记录
    
    Args:
        func: 要装饰的函数
        level: 日志级别
        extra_info: 额外信息
        re_raise: 是否重新抛出异常
        
    Returns:
        Callable: 装饰后的函数
    """
    return global_exception_logger.wrap(func, level, extra_info, re_raise)